% Run several benchmarking utilites for Snow Dots and plot the results.

%% Strobed words and clock comparisons
% benchmarkDOutStrobedWords() uses strobed word digital outputs from a
% dotsAllDOutObject instance, and an external data collection system, like
% Plexon or a USB device.  It compares time intervals between strobed words
% as "seen" four different clocks:
%   - a local "waitFunction" which waits for a given, nomainal duration
%   - a local "clockFunction" which returns a the local, curent time
%   - dotsAllDOutObject instance which returns output timestamps
%   - an external data collection which observes the strobed words as
%   inputs
%   .
% It compares intervals from the several sources to assess how mutually
% reliable they are.
% @details
% See benchmarkDOutStrobedWords() for details of how the test is run.
% @details
% This benchmark is highly hardware- and implementation-dependent.  As of
% the November2010 revision of Snow Dots, only one hardware configuration
% is implemented and capable of running benchmarkDOutStrobedWords():
%   - ditigal outputs using the dotsDOut1208FS class (which uses the
%   mexHID() mex function and the 1208FS USB device from Measurement
%   Computing)
%   - external data collection by Plexon, and Plexon data accessed via
%   dotsTheComputablesManager, using a dotsComputableFunction object and
%   the getIntervalFromPlexonSDK function.
%   .
% See the dotsDOut1208FS documentation for which pins correspond to which
% digital word bits.  The output word bits should be connected to the
% corresponding strobed word input bits of a Plexon acquisition system.
% @details
% Snow Dots may grow to support more types digital output or data
% collection.  In that case:
%   - the platform-correct implementaion of dotsAllDOutObject should be
%   specfied with dotsTheMachineConfiguration and accessed via the
%   "dOutClassname" shared property of dotsTheSwitchboard.
%   - alternative getExternalFunction functions should be defined here
%   below and selected at test time by uncommenting the platform-correct
%   definition.
%   .
clear
clear all
clc

% Access the platform-correct implementation of dotsAllDOutObject
dOutClassname = dotsTheSwitchboard.getSharedPropertyValue('dOutClassname');
dOutObject = feval(dOutClassname);

% Choose the platform-correct definition of "getExternalFunction":

% getExternalFunction using Plexon strobed words with
% dotsTheComputablesManager
cm = dotsTheComputablesManager.theObject;
getter = cm.newObject('dotsComputableFunction');
getter.computeFunction = @getIntervalFromPlexonSDK;
getter.prepareFunction = @()getIntervalFromPlexonSDK('init');
cm.mayComputeComputable(getter, true);
getExternalFunction = @()cm.mayComputeComputable(getter, false);

% getExternalFunction using some other means...
% getExternalFunction = ???


% Also choose platform-correct timing functions:

%waitFunction = @mglWaitSecs;
%waitFunction = @(t)unix(sprintf('sleep %f', t));
waitFunction = @pause;

%clockFunction = @mglGetSecs;
tic;
clockFunction = @toc;

% Choose some strobed words and intervals between repeated word pairs:
words = 0:20;
intervals = linspace(0,.5,20);

% Run the strobed word benchmarking!
%   it will plot its results
data = benchmarkDOutStrobedWords(dOutObject, ...
    getExternalFunction, waitFunction, clockFunction, words, intervals);

% Do any cleanup that getExternalFunction may requre
getter.prepareFunction = @()getIntervalFromPlexonSDK('close');
cm.mayComputeComputable(getter, true);


%% Remote ensemble client-server communications and clocks
% For a dotsClientEnsemble, using default network addresses provided by
% dotsTheMessenver, exchange many messages with a remote
% dotsEnsembleServer.  Show transaction data with:
%   - raw timing data and data integrity
%	- parameters used to convert betwen server-side and client-side timing
%   data
%   .
% The quality of the timing parameter estimates will depend on the number
% of data exchange @b iterations.  The parameters are clock drift rate and
% initial clock absolute offsets.
clear
clear all
clc

% chose an arbitrary number of messages to exchange
iterations = 1000;

% TODO: need to implement transaction benchmarking for client ensembles